package game;

import game.Audio.AudioResources;
import javafx.embed.swing.SwingFXUtils;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.image.Image;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import org.json.simple.parser.ParseException;

import javax.imageio.ImageIO;
import javax.sound.sampled.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.net.URISyntaxException;


public class MainMenu {
    StartMenu startMenu;
    MenuButton newGame;
    MenuButton options;
    MenuButton quit;
    Image background, gameTitleImg;
    public static Clip clip;

    double lastVolumeMusic;
    double lastVolumeMaster;

    boolean changingVolume = false;

    // Button sounds
    Clip clipS;

    public MainMenu(GraphicsContext gc) throws UnsupportedAudioFileException, IOException, LineUnavailableException, ParseException, URISyntaxException {
        lastVolumeMusic = Double.valueOf(Configuration.getInstance().getVolumeMusic());
        lastVolumeMaster = Double.valueOf(Configuration.getInstance().getVolumeMaster());

        try {
            BufferedImage bg = ImageIO.read(getClass().getClassLoader().getResourceAsStream("Images/Backgrounds/splash.bmp"));
            gameTitleImg = new Image(getClass().getClassLoader().getResourceAsStream("gametitle.png"));
            this.background = SwingFXUtils.toFXImage(bg, null);
        } catch (IOException e) {
            e.printStackTrace();
        }

        playMenuMusic();
        loadButtonSound();
        startMenu = new StartMenu(clip);
        startMenu.hideMenu();
    }


    public List<MenuButton> getMainButtons() {
        List<MenuButton> res = new ArrayList<MenuButton>();

        // Create buttons
        double posX = 20;
        double scaleHUD = 0.5;
        if (Helper.screenHeight() > 720) {
            scaleHUD = 0.75;
        }
        double posY = Helper.screenHeight() / 2.0;
        this.newGame = new MenuButton(posX, posY, Color.DARKGRAY, Color.LIGHTGREY, "New game", "start");
        res.add(newGame);

        posY += 3 * newGame.h;
        this.options = new MenuButton(posX, posY, Color.DARKGRAY, Color.LIGHTGREY, "Options", "options");
        res.add(options);

        posY += 6 * newGame.h;
        this.quit = new MenuButton(posX, posY, Color.DARKGRAY, Color.LIGHTGREY, "Quit", "quit");
        res.add(quit);

        return res;
    }

    public void playMenuMusic() throws IOException, UnsupportedAudioFileException, LineUnavailableException {
        String fileName = "audio/menu.wav";
        InputStream inputStream = AudioResources.class.getClassLoader().getResourceAsStream(fileName);
        //add buffer for mark/reset support
        InputStream bufferedIn = new BufferedInputStream(inputStream);
        AudioInputStream a = AudioSystem.getAudioInputStream(bufferedIn);
        AudioFormat format = a.getFormat();
        DataLine.Info info = new DataLine.Info(Clip.class, format);
        Clip nClip = (Clip) AudioSystem.getLine(info);
        if (this.clip != null) {
            this.clip.stop();
        }
        this.clip = nClip;
        clip.open(a);   // Open music file
        // Set volumen value
        FloatControl gainControl = (FloatControl) clip.getControl(FloatControl.Type.MASTER_GAIN);
        double gain = Double.valueOf(Configuration.getInstance().getVolumeMusic()) * Double.valueOf(Configuration.getInstance().getVolumeMaster()) / 10000; // gain entre 0 y 1
        float dB = (float) (Math.log(gain) / Math.log(10.0) * 20.0);
        gainControl.setValue(dB);
        clip.loop(-1);
        clip.start();      // Play clip
    }

    protected void loadButtonSound() throws IOException, UnsupportedAudioFileException, LineUnavailableException{
        String fileName = "audio/wpn_moveselect.wav";
        InputStream inputStream = AudioResources.class.getClassLoader().getResourceAsStream(fileName);
        InputStream bufferedIn = new BufferedInputStream(inputStream);

        AudioInputStream a = AudioSystem.getAudioInputStream(bufferedIn);
        AudioFormat format = a.getFormat();
        DataLine.Info info = new DataLine.Info(Clip.class, format);
        clipS = (Clip) AudioSystem.getLine(info);
        clipS.open(a);   // Open music file
    }
    public void playButtonSound()  {
        // Set volumen value
        FloatControl gainControl = (FloatControl) clipS.getControl(FloatControl.Type.MASTER_GAIN);
        double gain = Double.valueOf(Configuration.getInstance().getVolumeInterface()) * Double.valueOf(Configuration.getInstance().getVolumeMaster()) / 10000; // gain entre 0 y 1
        float dB = (float) (Math.log(gain) / Math.log(10.0) * 20.0);
        gainControl.setValue(dB);

        // Start clip
        if(clipS.isRunning())
            clipS.stop();
            clipS.setMicrosecondPosition(0);
        clipS.start();
    }

    public void playExitButtonSound() throws IOException, UnsupportedAudioFileException, LineUnavailableException {
        String fileName = "audio/wpn_select.wav";
        InputStream bottomSound = AudioResources.class.getClassLoader().getResourceAsStream(fileName);
        AudioInputStream a = AudioSystem.getAudioInputStream(bottomSound);
        AudioFormat format = a.getFormat();
        DataLine.Info info = new DataLine.Info(Clip.class, format);
        Clip clipS = (Clip) AudioSystem.getLine(info);
        clipS.open(a);   // Open music file
        // Set volumen value
        FloatControl gainControl = (FloatControl) clipS.getControl(FloatControl.Type.MASTER_GAIN);
        double gain = Double.valueOf(Configuration.getInstance().getVolumeInterface()) * Double.valueOf(Configuration.getInstance().getVolumeMaster()) / 10000; // gain entre 0 y 1
        float dB = (float) (Math.log(gain) / Math.log(10.0) * 20.0);
        gainControl.setValue(dB);
        clipS.start();      // Play clip
    }

    public void update(double deltaTime) {
        // Check for input (clicks)
        List<MenuButton> buttons = getMainButtons();
        String cmd = "";
        for (int i = 0; i < buttons.size(); i++) {
            if (buttons.get(i).isClicked()) {
                cmd = buttons.get(i).getClickString();
                break;
            }
        }

        // Do corresponding actions
        if (cmd == "start") {
            try {
                playButtonSound();
            } catch (Exception e) {
            }
            startMenu.showMenu();
        }
        if (cmd == "options") {
            try {
                playButtonSound();
            } catch (Exception e) {
            }
            new ConfigurationMenu();
        }
        if (cmd == "quit") {
            try {
                playExitButtonSound();
            } catch (Exception e) {
            }
            System.exit(0);
        }

        if (Double.valueOf(Configuration.getInstance().getVolumeMusic()) != lastVolumeMusic ||
                Double.valueOf(Configuration.getInstance().getVolumeMaster()) != lastVolumeMaster) {
            lastVolumeMusic = Double.valueOf(Configuration.getInstance().getVolumeMusic());
            lastVolumeMaster = Double.valueOf(Configuration.getInstance().getVolumeMaster());

            // Set volumen value
            FloatControl gainControl = (FloatControl) clip.getControl(FloatControl.Type.MASTER_GAIN);
            double gain = Double.valueOf(Configuration.getInstance().getVolumeMusic()) * Double.valueOf(Configuration.getInstance().getVolumeMaster()) / 10000; // gain entre 0 y 1
            float dB = (float) (Math.log(gain) / Math.log(10.0) * 20.0);
            gainControl.setValue(dB);
            changingVolume = true;
        }
        if (Scene.getInstance() == null && !changingVolume) {   // si no hay scene, estas en menu principal
            if (!clip.isRunning() && !startMenu.isLoading()) {
                try {
                    //clip.restart();
                    clip.setMicrosecondPosition(0);
                    clip.start();
                    //playMenuMusic();
                } catch (Exception e) {

                }
            }
        }
        changingVolume = false;
    }

    public void draw(GraphicsContext gd) {
        // Draw current menu
        double imageRatio = background.getWidth() / background.getHeight();
        double screenRatio = (double) Helper.screenWidth() / (double) Helper.screenHeight();



        double bgHeight = 0;
        if (imageRatio >= screenRatio)
        {
            bgHeight = Helper.screenHeight();
            gd.drawImage(background, 0, 0, Helper.screenHeight() * imageRatio, Helper.screenHeight());
        }else{
            bgHeight = Helper.screenWidth() / imageRatio;
            gd.drawImage(background, 0, 0, Helper.screenWidth(), Helper.screenWidth() / imageRatio);
        }

        double scaleHUD = 0.5;
        if (Helper.screenHeight() > 720) {
            scaleHUD = 0.75;
        }
        gd.setFont(new Font("Arial", 40 * scaleHUD));


        gd.drawImage(gameTitleImg, 18, Helper.screenHeight() / 2.0 - gameTitleImg.getHeight()*1.5*scaleHUD,
                gameTitleImg.getWidth()*scaleHUD,
                gameTitleImg.getHeight()*scaleHUD);
        List<MenuButton> buttons = getMainButtons();
        for (int i = 0; i < buttons.size(); i++) {
            buttons.get(i).draw(gd);
        }


        startMenu.draw(gd);
    }
}
